#include <commonheader.h>
#include "servermgr.h"

#include "sdsvrhandler.h"
#include "baseserver.h"
#include "../config/config.h"
#include "../framework/modulemgr.h"
#include "exelogger.h"

IMPLEMENT_SINGLETON(CServerMgr)

CServerMgr::CServerMgr()
{
}

CServerMgr::~CServerMgr()
{

}

bool CServerMgr::Init(ISDSvrHandlerMgr * poSvrHandlerMgr)
{
    if(CModuleMgr::Instance()->GetPipeModule() == NULL || CModuleMgr::Instance()->GetDBModule() == NULL)
    {
        SYS_CRITICAL("Either Pipe module or DB Module is NULL");
		return false;
    }

    m_poSvrHandlerMgr = poSvrHandlerMgr;

    if (!m_poSvrHandlerMgr->Init(this))
    {
        SYS_CRITICAL("SvrHandlerMgr:failed");
        return false;
    }

	char szPipeConfPath[MAX_PATH];
	sprintf(szPipeConfPath, "%s/%s", GetExePath(), CConfig::Instance()->GetPipeConf());

	char szIpListPath[MAX_PATH];
	sprintf(szIpListPath, "%s/%s", GetExePath(), CConfig::Instance()->GetIpList());

	if(!CModuleMgr::Instance()->GetPipeModule()->Init(szPipeConfPath, szIpListPath, this, CModuleMgr::Instance()->GetNetModule()))
    {
        SYS_CRITICAL("Pipe Module init failed");
		return false;
    }

    m_oServerPool.Init(MAX_SERVER_COUNT);

	return true;
}

void CServerMgr::OnReport(INT32 nErrCode, UINT32 dwID)
{
	if(nErrCode == SGDP::PIPE_SUCCESS)
		_OnConnected(nErrCode, dwID);
	else
    {
        SYS_CRITICAL("CServerMgr::OnReport(): nErrCode=%d, dwID=%x", nErrCode, dwID);
		_OnDisConnected(nErrCode, dwID);
    }
}

void CServerMgr::_OnConnected(INT32 nErrCode, UINT32 dwID)
{
	SGDP::SSDPipeId* pstPipeID = (SGDP::SSDPipeId*)&dwID;

    if (NULL == m_poSvrHandlerMgr)
    {
        return;
    }

    ISDSvrHandler* poPkgHandle = m_poSvrHandlerMgr->GetSvrHandler(pstPipeID->byType);
    if (NULL == poPkgHandle)
    {
        return;
    }

    CBaseServer * poSvr = m_oServerPool.FetchObj();
    if (NULL == poSvr)
    {
        return;
    }

    SGDP::ISDPipe* poPipe = CModuleMgr::Instance()->GetPipeModule()->GetPipe(dwID);
    if(poPipe == NULL)
    {
        SYS_CRITICAL("OnConnected: server pipe can not find: %x", dwID);
        return;
    }
    m_oServerMap[dwID] = poSvr;

    poPipe->SetSink(poPkgHandle->GetBusinessID(), poSvr);
    poSvr->Init(dwID, poPipe, poPkgHandle);
    poSvr->OnConnected();

    
}

void CServerMgr::_OnDisConnected(INT32 nErrCode, UINT32 dwID)
{ 
    SGDP::ISDPipe* poPipe = CModuleMgr::Instance()->GetPipeModule()->GetPipe(dwID);
    if(poPipe == NULL)
    {
        SYS_CRITICAL("OnDisConnected: server pipe can not find");
        return;
    }


    stdext::hash_map<UINT32, CBaseServer*>::iterator it = m_oServerMap.find(dwID);
    if (it != m_oServerMap.end())
    {
        CBaseServer * poSvr = it->second;
        poPipe->SetSink(poSvr->GetPkgHandle()->GetBusinessID(), NULL);
        poSvr->OnDisConnected(nErrCode);
        m_oServerMap.erase(it);
        poSvr->Reset();
        m_oServerPool.ReleaseObj(poSvr);
    }
}

bool CServerMgr::Send(UINT32 dwSvrID, const char * pszBuf, UINT32 dwBufLen)
{
    stdext::hash_map<UINT32, CBaseServer*>::iterator it = m_oServerMap.find(dwSvrID);
    if (it == m_oServerMap.end())
    {
        return false;
    }

    return it->second->Send(pszBuf, dwBufLen);
}
